package com.aries.ui.view.radius.delegate;


import com.aries.ui.util.AttrUtils;
import com.aries.ui.util.ResourceUtil;
import com.aries.ui.widget.ResourceTable;
import ohos.agp.animation.AnimatorValue;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.components.element.StateElement;
import ohos.agp.render.Paint;
import ohos.agp.render.Path;
import ohos.agp.render.Region;
import ohos.agp.utils.Color;
import ohos.agp.utils.Rect;
import ohos.agp.utils.RectFloat;
import ohos.app.Context;
import ohos.multimodalinput.event.TouchEvent;

/**
 * @Author: AriesHoo on 2018/7/19 10:01
 * @E-Mail: AriesHoo@126.com
 * Function:  公共属性解析代理类
 * Description:
 * 1、2017-11-15 09:36:14 添加Java属性设置链式调用支持
 * 2、2018-2-4 10:13:17 修改设置背景时机需调用init方法以设置避免未设置完所有属性不停调用设置背景
 * 3、2018-2-4 17:10:15 增加setSelected方法及对应的监听setOnSelectedChangeListener
 * 4、2018-2-5 13:36:02 修改不可点击属性Enabled对应修改为Disabled xml及java方法同步修改
 * 5、2018-2-6 12:04:02 校正float类型参数xml属性解析方法
 * 6、2018-2-23 10:30:53 新增View在非波纹背景下各个状态切换时延属性
 * 7、2018-3-18 11:17:29 新增泛型返回方便子类继承的链式调用
 * 8、2018-5-25 13:12:24 去掉默认控制是否可点击控制,调整水波纹效果开启逻辑
 * 9、2018-6-13 10:06:08 调整默认backgroundColor及strokeColor颜色值以优化
 * 10、2018-6-13 10:51:11 新增背景及边框色pressed状态下透明度属性-当且仅当未设置对应pressedColor时生效
 * 11、2018-11-23 13:13:30 修改设置水波纹逻辑解决xml设置enable false 预览有效果运行无效BUG
 */
public class RadiusViewDelegate<T extends RadiusViewDelegate> implements Component.TouchEventListener {

    protected ResourceUtil mResourceUtil;

    protected Component mView;
    private Context mContext;
    private ShapeElement mBackground = new ShapeElement();
    private ShapeElement mBackgroundPressed = new ShapeElement();
    private ShapeElement mBackgroundDisabled = new ShapeElement();
    private ShapeElement mBackgroundSelected = new ShapeElement();
    private ShapeElement mBackgroundChecked = new ShapeElement();

    //以下为xml属性对应解析参数

    private int mBackgroundColor;
    private int mBackgroundPressedColor;
    private int mBackgroundDisabledColor;
    private int mBackgroundSelectedColor;
    private int mBackgroundCheckedColor;
    protected int mBackgroundPressedAlpha = 0;

    private int mStrokeColor;
    private int mStrokePressedColor;
    private int mStrokeDisabledColor;
    private int mStrokeSelectedColor;
    private int mStrokeCheckedColor;
    protected int mStrokePressedAlpha = 0;

    private int mStrokeWidth;
    private float mStrokeDashWidth;
    private float mStrokeDashGap;

    private boolean mRadiusHalfHeightEnable;
    private boolean mWidthHeightEqualEnable;

    private float mRadius;
    private float mTopLeftRadius;
    private float mTopRightRadius;
    private float mBottomLeftRadius;
    private float mBottomRightRadius;

    public int mRippleColor;
    public boolean mRippleEnable;
    private boolean mSelected;
    private boolean mPressed;
    private int mEnterFadeDuration = 0;
    private int mExitFadeDuration = 0;
    //以上为xml属性对应解析参数

    protected int mStateChecked = ComponentState.COMPONENT_STATE_CHECKED;//**.R.attr.state_checked;
    protected int mStateSelected = ComponentState.COMPONENT_STATE_SELECTED;//**.R.attr.state_selected;
    protected int mStatePressed = ComponentState.COMPONENT_STATE_PRESSED;//**.R.attr.state_pressed;
    protected int mStateDisabled = ComponentState.COMPONENT_STATE_DISABLED;// -**.R.attr.state_enabled;
    ;
    private float[] mRadiusArr = new float[8];

    private OnSelectedChangeListener mOnSelectedChangeListener;

    //水波纹相关
    /*起始点*/
    private int mDownX;
    private int mDownY;

    private float mDensity;
    /*绘制的半径*/
    private float mDrawRadius;
    /*绘制的最大半径*/
    private float mMaxRadius;
    private float mStepRadius;
    private static final int DRAW_RADIUS_ZERO = 0;
    private static final int DRAW_RADIUS_MOVE = 100;

    private boolean mDrawFinish;
    private static final int DURATION = 400;
    private static final int FREQUENCY = 10;
    private float mCycle;
    private final Rect mRect = new Rect();
    private boolean mPressUp = false;
    private Paint mRevealPaint;

    private float mAlphaFactor = 0.5f;
    private boolean mHover = false;

    /*动画*/
    private AnimatorValue mRadiusAnimator;
    private int mDuration = 3000;

    private boolean isPointMove = false;

    /**
     * 状态栏高度,跟华为官方确认过了,目前还没有提供获取状态栏高度的方法
     */
    private int mStatusBarHeight;


    public int mPageBackgroundColor;

    public float[] radii = new float[8];   // top-left, top-right, bottom-right, bottom-left
    public Path mClipPath;                 // 剪裁区域路径
    public Paint mPaint;                   // 画笔
    public Region mAreaRegion;             // 内容区域
    public RectFloat mLayer;                   // 画布图层大小
    //水波纹结束


    public interface OnSelectedChangeListener {
        /**
         * Called when the checked state of a View has changed.
         *
         * @param view       The View whose state has changed.
         * @param isSelected The new selected state of buttonView.
         */
        void onSelectedChanged(Component view, boolean isSelected);
    }

    public RadiusViewDelegate(Component view, Context context, AttrSet attrs) {
        this.mView = view;
        this.mContext = context;
        //  this.mTypedArray = context.obtainStyledAttributes(attrs, R.styleable.RadiusSwitch);
        this.mResourceUtil = new ResourceUtil(context);
        mSelected = mView.isSelected();
        mPressed = mView.isPressed();
        initAttributes(context, attrs);
        view.setSelected(mSelected);
        setBackgroundPressedAlpha(mBackgroundPressedAlpha)
                .setStrokePressedAlpha(mStrokePressedAlpha)
                .setSelected(mSelected);
        mView.setTouchEventListener(this);
        mHover = mRippleEnable;
       /* if (mHover){
            mLayer = new RectFloat();
            mClipPath = new Path();
            mAreaRegion = new Region();
            mPaint = new Paint();
            mPaint.setColor(Color.WHITE);
            mPaint.setAntiAlias(true);
            initView();
            startAnimation();
            mView.addDrawTask(this);

        mView.setBindStateChangedListener(new Component.BindStateChangedListener() {
            @Override
            public void onComponentBoundToWindow(Component component) {
                mRect.set(component.getLeft(), component.getTop(), component.getRight(), component.getBottom());
                onSizeChanged(component,component.getWidth(),component.getHeight());
            }

            @Override
            public void onComponentUnboundFromWindow(Component component) {

            }
        });
        }*/
    }

    protected void initAttributes(Context context, AttrSet attrs) {
        mPageBackgroundColor = AttrUtils.getColorFromAttr(attrs, "rv_mPageBackgroundColor", ResourceTable.Color_colorBackground);
        mBackgroundColor = AttrUtils.getColorFromAttr(attrs, "rv_backgroundColor", Integer.MAX_VALUE);
        mBackgroundPressedColor = AttrUtils.getColorFromAttr(attrs, "rv_backgroundPressedColor", Integer.MAX_VALUE);
        mBackgroundDisabledColor = AttrUtils.getColorFromAttr(attrs, "rv_backgroundDisabledColor", Integer.MAX_VALUE);
        mBackgroundSelectedColor = AttrUtils.getColorFromAttr(attrs, "rv_backgroundSelectedColor", Integer.MAX_VALUE);
        mBackgroundCheckedColor = AttrUtils.getColorFromAttr(attrs, "rv_backgroundCheckedColor", Integer.MAX_VALUE);
        mBackgroundPressedAlpha = AttrUtils.getIntegerFromAttr(attrs, "rv_backgroundPressedAlpha", mBackgroundPressedAlpha);

        mStrokeColor = AttrUtils.getColorFromAttr(attrs, "rv_strokeColor", Integer.MAX_VALUE);
        mStrokePressedColor = AttrUtils.getColorFromAttr(attrs, "rv_strokePressedColor", Integer.MAX_VALUE);
        mStrokeDisabledColor = AttrUtils.getColorFromAttr(attrs, "rv_strokeDisabledColor", Integer.MAX_VALUE);
        mStrokeSelectedColor = AttrUtils.getColorFromAttr(attrs, "rv_strokeSelectedColor", Integer.MAX_VALUE);
        mStrokeCheckedColor = AttrUtils.getColorFromAttr(attrs, "rv_strokeCheckedColor", Integer.MAX_VALUE);
        mStrokePressedAlpha = AttrUtils.getIntegerFromAttr(attrs, "rv_strokePressedAlpha", mStrokePressedAlpha);

        mStrokeWidth = AttrUtils.getDimensionFromAttr(attrs, "rv_strokeWidth", 0);
        mStrokeDashWidth = AttrUtils.getDimensionFromAttr(attrs, "rv_strokeDashWidth", 0);
        mStrokeDashGap = AttrUtils.getDimensionFromAttr(attrs, "rv_strokeDashGap", 0);

        mRadiusHalfHeightEnable = AttrUtils.getBooleanFromAttr(attrs, "rv_radiusHalfHeightEnable", false);
        mWidthHeightEqualEnable = AttrUtils.getBooleanFromAttr(attrs, "rv_widthHeightEqualEnable", false);

        mRadius = AttrUtils.getDimensionFromAttr(attrs, "rv_radius", 0);

        mTopLeftRadius = AttrUtils.getDimensionFromAttr(attrs, "rv_topLeftRadius", 0);
        mTopRightRadius = AttrUtils.getDimensionFromAttr(attrs, "rv_topRightRadius", 0);
        mBottomLeftRadius = AttrUtils.getDimensionFromAttr(attrs, "rv_bottomLeftRadius", 0);
        mBottomRightRadius = AttrUtils.getDimensionFromAttr(attrs, "rv_bottomRightRadius", 0);

        mRippleColor = AttrUtils.getColorFromAttr(attrs, "rv_rippleColor", mResourceUtil.getColor(ResourceTable.Color_colorBackground));
        mRippleEnable = AttrUtils.getBooleanFromAttr(attrs, "rv_rippleEnable", false);
        mSelected = AttrUtils.getBooleanFromAttr(attrs, "rv_selected", mSelected);
        mEnterFadeDuration = AttrUtils.getIntegerFromAttr(attrs, "rv_enterFadeDuration", 0);
        mExitFadeDuration = AttrUtils.getIntegerFromAttr(attrs, "rv_exitFadeDuration", 0);
    }

    protected T back() {
        return (T) this;
    }

    /**
     * 设置常态背景色
     *
     * @param color
     * @return (T)this
     */
    public T setBackgroundColor(int color) {
        this.mBackgroundColor = color;
        return back();
    }

    /**
     * 设置按下状态背景色
     *
     * @param color
     * @return (T)this
     */
    public T setBackgroundPressedColor(int color) {
        this.mBackgroundPressedColor = color;
        return back();
    }

    /**
     * 设置不可操作状态下背景色
     *
     * @param color
     * @return (T)this
     */
    public T setBackgroundDisabledColor(int color) {
        this.mBackgroundDisabledColor = color;
        return back();
    }

    /**
     * 设置selected状态下背景色
     *
     * @param color
     * @return (T)this
     */
    public T setBackgroundSelectedColor(int color) {
        this.mBackgroundSelectedColor = color;
        return back();
    }

    /**
     * 设置checked状态背景色
     *
     * @param color
     * @return (T)this
     */
    public T setBackgroundCheckedColor(int color) {
        this.mBackgroundCheckedColor = color;
        return back();
    }

    /**
     * 背景色按下状态透明度(0-255默认102 仅当未设置backgroundPressedColor有效)
     *
     * @param alpha
     * @return (T)this
     */
    public T setBackgroundPressedAlpha(int alpha) {
        if (alpha > 255) {
            alpha = 255;
        } else if (alpha < 0) {
            alpha = 0;
        }
        this.mBackgroundPressedAlpha = alpha;
        return back();
    }

    /**
     * 设置边框线常态颜色
     *
     * @param strokeColor
     * @return (T)this
     */
    public T setStrokeColor(int strokeColor) {
        this.mStrokeColor = strokeColor;
        return back();
    }

    /**
     * 设置边框线按下状态颜色
     *
     * @param strokePressedColor
     * @return (T)this
     */
    public T setStrokePressedColor(int strokePressedColor) {
        this.mStrokePressedColor = strokePressedColor;
        return back();
    }

    /**
     * 设置边框线不可点击状态下颜色
     *
     * @param strokeDisabledColor
     * @return (T)this
     */
    public T setStrokeDisabledColor(int strokeDisabledColor) {
        this.mStrokeDisabledColor = strokeDisabledColor;
        return back();
    }

    /**
     * 设置边框线selected状态颜色
     *
     * @param strokeSelectedColor
     * @return (T)this
     */
    public T setStrokeSelectedColor(int strokeSelectedColor) {
        this.mStrokeSelectedColor = strokeSelectedColor;
        return back();
    }

    /**
     * 设置边框checked状态颜色
     *
     * @param strokeCheckedColor
     * @return (T)this
     */
    public T setStrokeCheckedColor(int strokeCheckedColor) {
        this.mStrokeCheckedColor = strokeCheckedColor;
        return back();
    }

    /**
     * 边框色按下状态透明度(0-255默认102 仅当未设置strokePressedColor有效)
     *
     * @param alpha
     * @return (T)this
     */
    public T setStrokePressedAlpha(int alpha) {
        if (alpha > 255) {
            alpha = 255;
        } else if (alpha < 0) {
            alpha = 0;
        }
        this.mStrokePressedAlpha = alpha;
        return back();
    }

    /**
     * 设置边框线宽度(粗细)
     *
     * @param strokeWidth
     * @return (T)this
     */
    public T setStrokeWidth(int strokeWidth) {
        this.mStrokeWidth = strokeWidth;
        return back();
    }

    /**
     * 设置虚线宽度
     *
     * @param strokeDashWidth
     * @return (T)this
     */
    public T setStrokeDashWidth(float strokeDashWidth) {
        this.mStrokeDashWidth = strokeDashWidth;
        return back();
    }

    /**
     * 设置虚线间隔
     *
     * @param strokeDashGap
     * @return (T)this
     */
    public T setStrokeDashGap(float strokeDashGap) {
        this.mStrokeDashGap = strokeDashGap;
        return back();
    }

    /**
     * 设置半高度圆角
     *
     * @param enable
     * @return (T)this
     */
    public T setRadiusHalfHeightEnable(boolean enable) {
        this.mRadiusHalfHeightEnable = enable;
        return back();
    }

    /**
     * 设置宽高相等
     *
     * @param enable
     * @return (T)this
     */
    public T setWidthHeightEqualEnable(boolean enable) {
        this.mWidthHeightEqualEnable = enable;
        return back();
    }

    /**
     * 设置整体圆角弧度
     *
     * @param radius
     * @return (T)this
     */
    public T setRadius(float radius) {
        this.mRadius = radius;
        return back();
    }

    /**
     * 设置左上圆角
     *
     * @param radius
     * @return (T)this
     */
    public T setTopLeftRadius(float radius) {
        this.mTopLeftRadius = radius;
        return back();
    }

    /**
     * 设置右上圆角
     *
     * @param radius
     * @return (T)this
     */
    public T setTopRightRadius(float radius) {
        this.mTopRightRadius = radius;
        return back();
    }

    /**
     * 设置左下圆角
     *
     * @param radius
     * @return (T)this
     */
    public T setBottomLeftRadius(float radius) {
        this.mBottomLeftRadius = radius;
        return back();
    }

    /**
     * 设置右下圆角
     *
     * @param radius
     * @return (T)this
     */
    public T setBottomRightRadius(float radius) {
        this.mBottomRightRadius = radius;
        return back();
    }

    /**
     * 设置水波纹颜色 5.0以上支持
     *
     * @param color
     * @return (T)this
     */
    public T setRippleColor(int color) {
        this.mRippleColor = color;
        return back();
    }

    /**
     * 设置是否支持水波纹效果--5.0及以上
     *
     * @param enable
     * @return (T)this
     */
    public T setRippleEnable(boolean enable) {
        this.mRippleEnable = enable;
        return back();
    }

    /**
     * 设置选中状态变换监听
     *
     * @param listener
     * @return (T)this
     */
    public T setOnSelectedChangeListener(OnSelectedChangeListener listener) {
        this.mOnSelectedChangeListener = listener;
        return back();
    }

    public void setSelected(boolean selected) {
        if (mView != null) {
            if (mSelected != selected) {
                mSelected = selected;
                if (mOnSelectedChangeListener != null) {
                    mOnSelectedChangeListener.onSelectedChanged(mView, mSelected);
                }
                mView.setSelected(selected);
            }
        }
    }

    /**
     * 设置状态切换延时
     *
     * @param duration
     * @return (T)this
     */
    public T setEnterFadeDuration(int duration) {
        if (duration >= 0) {
            mEnterFadeDuration = duration;
        }
        return back();
    }

    /**
     * 设置状态切换延时
     *
     * @param duration
     * @return (T)this
     */
    public T setExitFadeDuration(int duration) {
        if (duration > 0) {
            mExitFadeDuration = duration;
        }
        return back();
    }

    public float getRadius() {
        return mRadius;
    }

    public boolean getRadiusHalfHeightEnable() {
        return mRadiusHalfHeightEnable;
    }

    public boolean getWidthHeightEqualEnable() {
        return mWidthHeightEqualEnable;
    }

    /**
     * 设置 背景Drawable颜色线框色及圆角值
     *
     * @param gd
     * @param color
     * @param strokeColor
     */
    private void setDrawable(ShapeElement gd, int color, int strokeColor) {
        //任意值大于0执行
        if (mTopLeftRadius > 0 || mTopRightRadius > 0 || mBottomRightRadius > 0 || mBottomLeftRadius > 0) {
            mRadiusArr[0] = mTopLeftRadius;
            mRadiusArr[1] = mTopLeftRadius;
            mRadiusArr[2] = mTopRightRadius;
            mRadiusArr[3] = mTopRightRadius;
            mRadiusArr[4] = mBottomRightRadius;
            mRadiusArr[5] = mBottomRightRadius;
            mRadiusArr[6] = mBottomLeftRadius;
            mRadiusArr[7] = mBottomLeftRadius;
            gd.setCornerRadiiArray(mRadiusArr);
        } else {
            gd.setCornerRadius(mRadius);
        }
        gd.setStroke(mStrokeWidth, RgbColor.fromArgbInt(getStrokeColor(strokeColor)));
        if (mStrokeDashWidth > 0 && mStrokeDashGap > 0) {
            float[] intervals = new float[]{mStrokeDashWidth, mStrokeDashGap};
            gd.setDashPathEffectValues(intervals, 0);
        }
        gd.setRgbColor(RgbColor.fromArgbInt(getBackColor(color)));
    }

    /**
     * 设置shape属性
     * 设置完所有属性后调用设置背景
     */
    public void init() {
        //获取view当前drawable--用于判断是否通过默认属性设置背景
        mView.getBackgroundElement();
        //判断是否使用自定义颜色值
        boolean isSetBg = mBackgroundColor != Integer.MAX_VALUE
                || mBackgroundPressedColor != Integer.MAX_VALUE
                || mBackgroundDisabledColor != Integer.MAX_VALUE
                || mBackgroundSelectedColor != Integer.MAX_VALUE
                || mStrokeWidth > 0 || mRadius > 0
                || mTopLeftRadius > 0 || mTopRightRadius > 0 || mBottomLeftRadius > 0 || mBottomRightRadius > 0;


        setDrawable(mBackgroundChecked, mBackgroundCheckedColor, mStrokeCheckedColor);
        setDrawable(mBackgroundSelected, mBackgroundSelectedColor, mStrokeSelectedColor);
        setDrawable(mBackground, mBackgroundColor, mStrokeColor);
        //水波纹
        if (mRippleEnable && mView.isEnabled()) {

            mView.setBackground(mBackground);
            return;
        }
        if (!isSetBg) {
            return;
        }
        setDrawable(mBackgroundPressed, mBackgroundPressedColor, mStrokePressedColor);
        setDrawable(mBackgroundDisabled, mBackgroundDisabledColor, mStrokeDisabledColor);
        StateElement mStateDrawable = new StateElement();
        mStateDrawable.setEnterFadeDuration(mEnterFadeDuration);
        mStateDrawable.setExitFadeDuration(mExitFadeDuration);

        mStateDrawable.addState(new int[]{mStatePressed}, mBackgroundPressed);
        mStateDrawable.addState(new int[]{mStateSelected}, mBackgroundSelected);
        mStateDrawable.addState(new int[]{mStateChecked}, mBackgroundChecked);
        mStateDrawable.addState(new int[]{mStateDisabled}, mBackgroundDisabled);
        //默认状态--放置在最后否则其它状态不生效
        mStateDrawable.addState(new int[]{}, mBackground);
            /*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
                mView.setBackground(mStateDrawable);
            } else {*/
        mView.setBackground(mStateDrawable);
        return;
    }

    /**
     * 获取背景色
     *
     * @param color
     * @return backColor
     */
    private int getBackColor(int color) {
        if (color != Integer.MAX_VALUE) {
            return color;
        }
        if (mView.isSelected()) {
            color = mBackgroundSelectedColor;
        } else if (mView instanceof AbsButton) {
            if (((AbsButton) mView).isChecked()) {
                color = mBackgroundCheckedColor;
            }
        }
        int temp = mBackgroundColor == Integer.MAX_VALUE ? Color.WHITE.getValue() : mBackgroundColor;
        color = color != Integer.MAX_VALUE ? color : temp;
        return mView.isPressed() && !mRippleEnable ? calculateColor(color, mBackgroundPressedAlpha) : color;
    }

    /**
     * 获取边框线颜色
     *
     * @param color
     * @return strokeColor
     */
    private int getStrokeColor(int color) {
        if (color != Integer.MAX_VALUE) {
            return color;
        }
        if (mView.isSelected()) {
            color = mStrokeSelectedColor;
        } else if (mView instanceof AbsButton) {
            if (((AbsButton) mView).isChecked()) {
                color = mStrokeCheckedColor;
            }
        }
        int temp = mStrokeColor == Integer.MAX_VALUE ? Color.TRANSPARENT.getValue() : mStrokeColor;
        color = color != Integer.MAX_VALUE ? color : temp;
        return mView.isPressed() && !mRippleEnable ? calculateColor(color, mStrokePressedAlpha) : color;
    }

    /**
     * 水波纹效果完成后最终展示的背景Drawable
     *
     * @param mDrawable
     * @param isSetBg
     * @return ShapeElement
     */
    private ShapeElement getContentDrawable(ShapeElement mDrawable, boolean isSetBg) {
        if (mView instanceof AbsButton) {
            ShapeElement temp2 = mView.isSelected() ? mBackgroundSelected : mBackground;
            ShapeElement temp1 = ((AbsButton) mView).isChecked() ? mBackgroundChecked : temp2;
            return !isSetBg ? mDrawable : temp1;
        }
        ShapeElement temp = mView.isSelected() ? mBackgroundSelected : mBackground;
        return !isSetBg ? mDrawable : temp;
    }


    /**
     * 给颜色值添加透明度
     *
     * @param color color值
     * @param alpha alpha值 0-255
     * @return 最终的状态栏颜色
     */
    public int calculateColor(int color, int alpha) {
        if (alpha == 0) {
            return color;
        }
        float a = (float) (1 - (double) alpha / (double) 255f);
        int red = color >> 16 & 0xff;
        int green = color >> 8 & 0xff;
        int blue = color & 0xff;
        red = (int) (red * a + 0.5);
        green = (int) (green * a + 0.5);
        blue = (int) (blue * a + 0.5);
        return 0xff << 24 | red << 16 | green << 8 | blue;
    }


    private int dp(int dp) {
        return (int) (dp * (double) mDensity + 0.5d);
    }


    @Override
    public boolean onTouchEvent(Component component, TouchEvent touchEvent) {
        int action = touchEvent.getAction();
        isPointMove = false;
        if (!mView.isEnabled() && !mView.isClickable()) {
            return false;
        }
        switch (action) {
            case TouchEvent.PRIMARY_POINT_DOWN: {
                mView.setPressState(true);
                break;
            }
            case TouchEvent.POINT_MOVE:
                int index = touchEvent.getIndex();
                int x = (int) touchEvent.getPointerScreenPosition(index).getX();
                int y = (int) touchEvent.getPointerScreenPosition(index).getY();
                if (isOutsideView(x, y)) {
                    mView.setPressState(false);
                }
                break;
            case TouchEvent.CANCEL:
                break;
            case TouchEvent.PRIMARY_POINT_UP:
                mView.setPressState(false);
                break;
        }
        return true;
    }

    /**
     * touch是否移出view之外
     *
     * @param x touchEvent.getPointerScreenPosition.getX()
     * @param y touchEvent.getPointerScreenPosition.getY()
     * @return boolean 是否超出View范围之外
     */
    protected boolean isOutsideView(int x, int y) {
        int[] location = mView.getLocationOnScreen();
        int pointx = x - location[0];
        int pointy = y - location[1];
        boolean flag = false;
        Rect rect = new Rect();
        mView.getSelfVisibleRect(rect);
        if (!rect.isInclude(pointx, pointy)) {
            flag = true;
        }
        return flag;
    }


    public Context getmContext() {
        return mContext;
    }

    public boolean ismPressUp() {
        return mPressUp;
    }

    public float getmAlphaFactor() {
        return mAlphaFactor;
    }

    public boolean ismHover() {
        return mHover;
    }

    public int getmDuration() {
        return mDuration;
    }

    public boolean isPointMove() {
        return isPointMove;
    }

    public float getmCycle() {
        return mCycle;
    }

    public ResourceUtil getmResourceUtil() {
        return mResourceUtil;
    }

    public int getmDownX() {
        return mDownX;
    }

    public int getmDownY() {
        return mDownY;
    }

    public float getmDrawRadius() {
        return mDrawRadius;
    }

    public float getmMaxRadius() {
        return mMaxRadius;
    }

    public float getmStepRadius() {
        return mStepRadius;
    }

    public boolean ismPressed() {
        return mPressed;
    }

    public int getmStatusBarHeight() {
        return mStatusBarHeight;
    }

    public Paint getmRevealPaint() {
        return mRevealPaint;
    }

    public AnimatorValue getmRadiusAnimator() {
        return mRadiusAnimator;
    }

    public boolean ismDrawFinish() {
        return mDrawFinish;
    }
}
